﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web;
using Common.Paging;

namespace Common.Extensions
{
    /// <summary>
    /// Extensions für das Paging
    /// http://code-inside.de/blog/2008/04/01/aspnet-mvc-paging-implementieren/
    /// </summary>
    public static class PagingExtensions
    {
        /// <summary>
        /// URL-Parameter, welcher die Seite angibt die angezeigt werden soll
        /// </summary>
        public static string UrlPage = "page";


        public static Paging<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
        {
            return new Paging<T>(source, index, pageSize);
        }

        public static Paging<T> ToPagedList<T>(this IEnumerable<T> source, int index, int pageSize)
        {
            return new Paging<T>(source, index, pageSize);
        }

        /// <summary>
        /// Ermittelt den aktuellen PageIndex, anhand der aktuellen URL Parameter.
        /// Wenn keine URL Parameter existiert, dann wird als PageIndex 0 zurückgegeben.
        /// </summary>
        public static int CurrentPageIndex()
        {
            //Ermitteln ob in der URL bereits die Page angegeben wird die angezeigt werden soll
            string urlPage = HttpContext.Current.Request.Params[PagingExtensions.UrlPage];

            //Wenn keine Page in der URL angezeigt wird, dann 
            if (string.IsNullOrEmpty(urlPage))
            {
                urlPage = "0";
            }

            //Ermitteln um welchen Pageindex es sich handelt, der gerade angezeigt wird.
            int pageIndex = 0;
            int.TryParse(urlPage, out pageIndex);

            return pageIndex;
        }

        /// <summary>
        /// Gibt die passenden Datensätze für die aktuelle Seite zurück, die Seite wird anhand der URL-Parameter ermittelt "page"
        /// </summary>
        /// <param name="pageSize">Die Seitengröße mit der gerechnet wird.</param>
        public static IEnumerable<T> CurrentPageEntries<T>(this IEnumerable<T> source, int pageSize)
        {
            //Versuchen aus der URL auszulesen, welche Page angezeigt werden soll.
            string urlPage = HttpContext.Current.Request.Params[UrlPage];
            //Wenn keine Seite gefunden werden konnte, bedeutet dies es wird die erste Seite angezeigt.
            if (urlPage == null)
            {
                urlPage = "1";
            }

            int index = 1;
            if (int.TryParse(urlPage, out index))
            {
                //Die passende Seite heraussuchen und zurückgegeben
                return source.Skip(index * pageSize).Take(pageSize);
            }


            //Die erste Seite zurückgeben, bei einem Fehler mit dem Index
            return source.Skip(index * pageSize).Take(pageSize);
        }

        /// <summary>
        /// Gibt die passende Seite mit den Datensätzen zurück, abhängig von der Pagesize. der Index welche Seite angezeigt werden soll wird aus der URL ermittelt,
        /// anhand der des "page" Url Parameters.
        /// </summary>
        /// <param name="pageSize">Die Seitengröße mit der gerechnet wird.</param>
        /// <returns>Die Sortierte passende Seite.</returns>
        public static IEnumerable<T> CurrentPageEntriesOrderByUrl<T>(this IEnumerable<T> source, int pageSize)
        {
            //Versuchen aus der URL auszulesen, welche Page angezeigt werden soll.
            string urlPage = HttpContext.Current.Request.Params[UrlPage];
            //Wenn keine Seite gefunden werden konnte, bedeutet dies es wird die erste Seite angezeigt.
            if (urlPage == null)
            {
                //Tage und Skip fangen bein 0 an zu zählen mit dem Index
                urlPage = "0";
            }

            int index = 1;
            //Ermitteln der Seite die angezeigt werden soll.
            if (int.TryParse(urlPage, out index))
            {
                //Erst sortieren der Daten, dann werden die passenden DS genommen die angezeigt werden sollen.
                return source.OrderByUrlParams().Skip(index * pageSize).Take(pageSize);
            }

            //Die erste Seite zurückgeben, bei einem Fehler mit dem Index
            return source.OrderByUrlParams().Skip(0).Take(pageSize);
        }
    }
}
